package cn.tyz.kotlin.ui

import android.content.Intent
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import cn.tyz.kotlin.R
import cn.tyz.kotlin.inter.OnItemClickListener
import cn.tyz.kotlin.model.Page
import cn.tyz.kotlin.model.Person2
import kotlinx.android.synthetic.main.activity_main.*
import org.jetbrains.anko.padding

class MainActivity : BaseActivity(),OnItemClickListener {

//    private lateinit var helloWorld: TextView
//    private lateinit var open_next: TextView

/** lateinit：延迟初始化属性
        lateinit 只能用在var类型
        lateinit不能用在可空的属性上和Java的基本类型上; 而lazy在第一次被调用时就被初始化，想要被改变只能重新定义
        lateinit 有支持（反向）域（Backing Fields）

不用findViewById,直接使用xml控件我们需要在gradle加入apply plugin: ‘kotlin-android-extensions' 然后导包

属性和字段：
var和val     val只读，常量类似final，只能赋值一次
var是允许有getter和 setter方法，如果变量是val声明的，它类似于Java中的final，所以如果以val声明就不允许有setter方法。

注意:全局变量一定得初始化,而局部变量可以不初始化,这是和java不同的地方
 */

/**
    有了这个插件才可以使用Kotlin，然后才可以使用Anko，就可以不用xml写布局
    在build.gradle里添加下面的代码：
    dependencies {
        compile 'org.jetbrains.anko:anko-sdk15:0.8.3' // sdk19, sdk21, sdk23 are also available
        compile 'org.jetbrains.anko:anko-support-v4:0.8.3' // In case you need support-v4 bindings
        compile 'org.jetbrains.anko:anko-appcompat-v7:0.8.3' // For appcompat-v7 bindings
    }
    */
    override fun onCreate(savedInstanceState: Bundle?) {    // ？表示可能为空
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        recycler_view.layoutManager = LinearLayoutManager(this)
        recycler_view.adapter = MainAdapter(items as List<Page<BaseActivity>>, this)

    }

    val items = listOf( // 不可变
            Page("流程控制", Note01DataType::class.java )
            ,Page("返回与跳转", Note01DataType::class.java )
            ,Page("函数扩展", Note01DataType::class.java )

            ,Page("进制自动转换", ChangeDataActivity::class.java )
            ,Page("基本数据类型", Note01DataType::class.java )
            ,Page("基本语法", BasicActivity::class.java )
            ,Page("对象", ObjectActivity::class.java )
            ,Page("流程控制", BasicActivity::class.java )
            ,Page("接口", Note05Interface::class.java )
            ,Page("集合、区间", Note11CollectionsActivity::class.java )
            ,Page("Volley 方式加载", MoveActivity::class.java )
            ,Page("RxJava 方式加载", MoveActivity2::class.java )


            ,Page("圆角矩形图片", PrettyImageViewActivity::class.java )

    )

    override fun onItemClick(position: Int) {
        try {
            Log.i("OnItemClick",items[position].name)
            when(position){
                0 ->  showControl()
                1 ->  showJump()
                2 -> showExpandFun()
                else -> startActivity(Intent(MainActivity@this, items[position].page))
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    class MainAdapter<BaseActivity>() : RecyclerView.Adapter<MainAdapter.ViewHolder>() {
        var items  : List<Page<BaseActivity>>? = null
        var itemClickListerner: OnItemClickListener? = null

        constructor(items : List<Page<BaseActivity>>, itemClickListerner: OnItemClickListener): this(){
            this.itemClickListerner = itemClickListerner
            this.items=items
        }
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val  textView = TextView(parent.context)
            textView.padding = 20
            textView.textSize = 20.0f
            return ViewHolder(textView)
        }

        override fun getItemCount(): Int =items!!.size

        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            try {
                holder.textView.text = items!![position].name
                holder.textView.setOnClickListener(View.OnClickListener { itemClickListerner?.onItemClick(position) })
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        class ViewHolder(var textView: TextView) : RecyclerView.ViewHolder(textView)
    }


    /** 01 流程控制: if , when , for , while*/
    fun showControl(){
        Log.i("kotlin", "========================showControl=====================")
        val a = 8;
        val b = 10
        val max = if (a > b){
            print("Choose a")
            a
        }
        else{
            print("Choose b")
            b
        }
        Log.i("kotlin","使用if  $max")
        Log.i("kotlin","使用 for 循环 (i in 1..5)")
        for(i in 1..5){
            Log.i("kotlin","list item "+i)
        }

        Log.i("kotlin","使用 for 循环 (item in items)")
        val items = listOf("apple", "banana",  "anim","kiwi")
        for (item in items) {
            Log.i("kotlin",item)    // println
        }

        Log.i("kotlin","智能字符串  使用 for 循环 (index in items.indices)")
        for (index in items.indices) {
            Log.i("kotlin","item at $index is ${items[index]}")
        }

        Log.i("kotlin","使用while循环 while (index < items.size)")
        var index = 0
        while (index < items.size) {
            println("item at $index is ${items[index]}")
            index++
        }

        Log.i("kotlin","使用lambda表达式过滤和映射集合")
        items.filter { it.startsWith("a") }
                .sortedBy { it }
                .map { it.toUpperCase() }
                .forEach { println(it) }

        Log.i("kotlin","使用 when 取代了 C 风格语言的 switch")
        val m = 3
        when (m) {
            1 -> print("x == 1")
            2 -> print("x == 2")
            3,4 -> Log.i("kotlin","x == 3 or x == 4")
            else -> { // Note the block
                Log.i("kotlin","x is neither 1 nor 2")
            }
        }

        Log.i("kotlin","使用ranges  if (x in 1..y+1)")
        val x = 10
        val y = 9
        if (x in 1..y+1) {
            Log.i("kotlin","fits in range")
        }
    }

    /** 02 返回与跳转
      标签字符后跟@符号
     * */
    fun  showJump(){
        Log.i("kotlin", "========================showReturn=====================")
//        标签通过 @ 结尾来表示
        var list :ArrayList<String> = arrayListOf()
        loop@
        for (i in 1..10) {
            if(i == 10){
                break@loop
            }else{
                list?.add("list "+i)    // ? list为空的时候，后面不执行
            }
        }

        Log.i("kotlin","用匿名函数")
        list.forEach  tag@{
            if(it == "list 5")  {
                Log.e("kotlin", it)
                return@tag
            }
            Log.i("kotlin", it)
        }

        Log.i("kotlin","用更方便的含蓄的标签return@forEach")
        list.forEach{
            if(it == "list 5")  {
                Log.e("kotlin", it)
                return@forEach
            }
            Log.i("kotlin", it)
        }

        Log.i("kotlin","用函数表达式替代匿名函数,在函数表达式中使用 return 语句可以从函数表达式中返回")
        list.forEach ( fun(value :String){
            if(value == "list 5") return
            Log.e("kotlin", value)
        })
    }

    /** 03 类和继承*/
    fun  showExtention(){
/**     https://github.com/huanglizhuo/kotlin-in-chinese/blob/master/ClassesAndObjects/Classes-and-Inheritance.md
        在 Kotlin 中声明  class Invoice { }
        构造函数  class Person constructor(firstName: String) { }
        如果主构造函数没有注解或可见性说明，则 constructor 关键字是可以省略  class Person(firstName: String){ }
        主构造函数不能包含任意代码。初始化代码可以放在以 init 做前缀的初始化块内
        class Customer(name: String) {
            init {
                logger,info("Customer initialized with value ${name}")
            }
        }
        注意主构造函数的参数可以用在初始化块内，也可以用在类的属性初始化声明处：
        class Customer(name: String) {
            val customerKry = name.toUpperCase()
        }
        class Person(val firstName: String, val lastName: String, var age: Int) {  }

        如果构造函数有注解或可见性声明，则 constructor 关键字是不可少的，并且可见性应该在前
        class Customer public @inject constructor (name: String) {...}

        二级构造函数
        类也可以有二级构造函数，需要加前缀 constructor:
        class Person {
            constructor(parent: Person) {
                parent.children.add(this)
            }
        }
        标记为override的成员是open的，它可以在子类中被复写。如果你不想被重写就要加 final:

        open class A {
            open fun f () { print("A") }
            fun a() { print("a") }
        }

        interface B {
            fun f() { print("B") } // 接口的成员变量默认是 open 的
            fun b() { print("b") }
        }

        class C() : A() , B {
            // 编译器会要求复写f()  必须复写 f() 并且提供自己的实现来消除歧义
            override fun f() {
                super<A>.f() // 调用 A.f()
                super<B>.f() // 调用 B.f()
            }
        }
        抽象类
        记住我们不用给一个抽象类或函数添加 open 注解，它默认是带着的。
        abstract class Derived : Base() {
            override abstract fun f()
        }

        密封类 密封类可以有子类但必须全部嵌套在密封类声明内部
        sealed class Expr {
            class Const(val number: Double) : Expr()
            class Sum(val e1: Expr, val e2: Expr) : Expr()
            object NotANumber : Expr()
        }
*/

        var p = Person2(2 , "kotlin","helloWorld")
        var i = Person2.TAG_SIZE    // 静态块

    }

    /** 04 可见性修饰词
    Kotlin 中有四种修饰词：private,protected,internal,以及 public 。默认的修饰符是 public
    internal val baz = 6 // 在同一module中可见  模块在 Kotlin 中就是一系列的 Kotlin 文件编译在一起
     * */

    /** 05 函数扩展  */
    fun showExpandFun(){
        Log.i("kotlin", "========================showExpandFun=====================")
        val resutl = mutableListOf(1, 2, 3) // 动态list
        resutl.swap(1, 2)// 在 `swap()` 函数中 `this` 持有的值是 `resutl`
        Log.i("kotlin", "$resutl")


    }

    fun MutableList<Int>.swap(x: Int, y: Int) {
        val tmp = this[x] // this 对应 list
        this[x] = this[y]
        this[y] = tmp
    }

//==========继承=============================
/*
    参数继承
    view instanceof Button to view is Button

    class继承
    class MainActivity : AppCompatActivity(){}*/

//    使用 when 表达式
    fun describe(obj: Any): String =
            when (obj) {
                1          -> "One"
                "Hello"    -> "Greeting"
                is Long    -> "Long"
                !is String -> "Not a string"
                else       -> "Unknown"
            }

}
